#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

struct msg {
  struct msg *next;
  int id;
};

struct msg *workq;
pthread_mutex_t qlock = PTHREAD_MUTEX_INITIALIZER;


void process_msg() {
  struct msg* mp;
  for(;;) {
    pthread_mutex_lock(&qlock);
    while(workq == NULL) {
      printf("检查队列\n");
      pthread_mutex_unlock(&qlock);
      sleep(1); // 让出 cpu，将控制权交给 enqueue_msg_fn
      pthread_mutex_lock(&qlock);
    }

    mp = workq;
    workq = mp->next;
    pthread_mutex_unlock(&qlock);
    // process message mp
    printf("message id : %4d\n", mp->id);
    free(mp);
  }
}

void enqueue_msg(struct msg *mp) {
  pthread_mutex_lock(&qlock);
  mp->next = workq;
  workq = mp;
  pthread_mutex_unlock(&qlock);
  printf("生产完成\n");
}

void* process_msg_fn(void *arg) {
  process_msg();
  return NULL;
}

void* enqueue_msg_fn(void *arg) {
  int i;
  struct msg *mp;
  for (i = 0; i < 5; ++i) {
    mp = (struct msg*)malloc(sizeof(struct msg));
    mp->id = i;
    mp->next = NULL;
    sleep(3);
    enqueue_msg(mp);
  }
  return NULL;
}

int main() {
  pthread_t tid1, tid2;
  pthread_create(&tid1, NULL, process_msg_fn, NULL);
  pthread_create(&tid2, NULL, enqueue_msg_fn, NULL);
  pthread_join(tid1, NULL);
  pthread_join(tid2, NULL);
  return 0;
}
